import path from 'path';
import { fileURLToPath } from 'url';
import webpack from 'webpack';
import { VueLoaderPlugin } from 'vue-loader';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import { CleanWebpackPlugin } from 'clean-webpack-plugin';

// 解决 ESM 中 __dirname 的替代方案
const __dirname = path.dirname(fileURLToPath(import.meta.url));

export default {
  // 入口配置
  entry: './src/main.js', // 支持字符串、数组或对象形式的多入口 [1,6](@ref)

  // 输出配置
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'js/[name].[contenthash:8].js', // 使用哈希和分块命名 [2,6](@ref)
    publicPath: '/', // 静态资源路径前缀 [1](@ref)
    assetModuleFilename: 'assets/[hash][ext][query]' // Webpack 5 资源文件输出规则 [6](@ref)
  },

  // 模块处理规则
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader' // 处理 Vue 单文件组件 [6](@ref)
      },
      {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader',
          'postcss-loader' // 添加 CSS 后处理器 [2](@ref)
        ]
      },
      {
        test: /\.less$/,
        use: [
          'style-loader',
          'css-loader',
          'postcss-loader',
          'less-loader' // 支持 Less 预处理器 [4](@ref)
        ]
      },
      {
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        type: 'asset/resource', // Webpack 5 资源模块 [6](@ref)
        generator: {
          filename: 'images/[hash][ext][query]' // 图片输出路径
        }
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/,
        type: 'asset/resource', // 字体文件处理 [4](@ref)
        generator: {
          filename: 'fonts/[hash][ext][query]'
        }
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader', // ES6+ 转译 [6](@ref)
          options: {
            presets: ['@babel/preset-env']
          }
        }
      }
    ]
  },

  // 插件配置
  plugins: [
    new VueLoaderPlugin(), // Vue 加载器插件 [6](@ref)
    new HtmlWebpackPlugin({
      template: './public/index.html', // 指定 HTML 模板 [2,5](@ref)
      favicon: './public/favicon.ico', // 图标处理
      minify: {
        collapseWhitespace: true // 生产环境压缩 HTML [7](@ref)
      }
    }),
    new CleanWebpackPlugin(), // 构建前清理 dist 目录 [2](@ref)
    new webpack.DefinePlugin({
      __VUE_OPTIONS_API__: true, // Vue 3 兼容性配置
      __VUE_PROD_DEVTOOLS__: false
    })
  ],

  // 解析配置
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src'), // 路径别名 [1](@ref)
      'vue$': 'vue/dist/vue.esm-bundler.js' // Vue 3 运行时编译器 [6](@ref)
    },
    extensions: ['.js', '.vue', '.json'] // 自动解析扩展名 [1](@ref)
  },

  // 开发服务器配置
  devServer: {
    static: {
      directory: path.join(__dirname, 'public'), // 静态资源目录 [6](@ref)
    },
    compress: true, // 启用 gzip 压缩 [4](@ref)
    port: 8080,
    hot: true, // 热模块替换 [5](@ref)
    historyApiFallback: true, // SPA 路由支持 [6](@ref)
    proxy: {
      '/api': {
        target: 'http://localhost:3000', // 代理 API 请求 [4](@ref)
        changeOrigin: true
      }
    }
  },

  // 优化配置
  optimization: {
    splitChunks: {
      chunks: 'all', // 代码分割策略 [6,7](@ref)
      cacheGroups: {
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          chunks: 'all'
        }
      }
    },
    runtimeChunk: 'single' // 提取 runtime 代码 [7](@ref)
  },

  // 模式配置
  mode: process.env.NODE_ENV || 'development', // 通过环境变量切换模式 [3](@ref)

  // 开发工具配置
  devtool: process.env.NODE_ENV === 'production'
    ? 'source-map'
    : 'eval-cheap-module-source-map' // 不同环境的 source map 策略 [6](@ref)
};